package com.ruoyi.common.handler;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @Classname ColumnMetaObjectHandler
 * @Author: sunluquan
 * @Date: 2021/12/17 11:18
 * @Description TODO
 * 新增修改默认属性值填充处理对象
 */
@Component
public class ColumnMetaObjectHandler implements MetaObjectHandler {


    @Override
    public void insertFill(MetaObject metaObject) {

        fill(filterNotFillField(metaObject, GenConstants.insertFillMap,FieldFill.INSERT),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {

        fill(filterNotFillField(metaObject,GenConstants.updateFillMap,FieldFill.UPDATE),metaObject);
    }

    /**
     * 对于填充对象映射 fillMap中有的属性  但是 metaObject元对象 也有的属性  但是这个属性没有标记 {@link FieldFill}
     * @param metaObject 元对象
     * @param fillMap 需要填充的属性
     * @param fieldFill 元对象上是否有该属性 且 该属性是否有注解 {@link com.baomidou.mybatisplus.annotation.TableField} 并且 其中的属性 {@link FieldFill} 是否等于 fieldFill
     * @return
     */
    private Map<String,Supplier<Object>> filterNotFillField(MetaObject metaObject , Map<String,Supplier<Object>> fillMap, FieldFill fieldFill){
        List<TableFieldInfo> fieldList = findTableInfo(metaObject).getFieldList();

        Map<String,Supplier<Object>> currentInsertFillMap = new HashMap<>(fillMap.size());

        fieldList.forEach(field->{
            String fieldName = field.getField().getName();
            if(field.getFieldFill()==fieldFill && fillMap.containsKey(fieldName)){
                currentInsertFillMap.put(fieldName,fillMap.get(fieldName));
            }
        });

        return currentInsertFillMap;
    }
    /**
     * 进行值填充 如果有值则忽略
     * @param fillMap
     * @param metaObject
     */
    private void fill(Map<String, Supplier<Object>> fillMap, MetaObject metaObject) {

        fillMap.forEach((k,v)->{
            //只填充不覆盖  如果有值则不进行处理
            if(metaObject.hasGetter(k) && StringUtils.isNull(metaObject.getValue(k))){
                Object value = v.get();
                //k属性名称  value 值
                fillStrategy(metaObject,k, value);
            }
        });
    }


}
